package io.shuttle.mbe.api

import io.shuttle.mbe.api.annotation.ChromeMinVersion
import io.shuttle.mbe.api.annotation.PromiseStyleMinVersion
import io.shuttle.mbe.api.types.Value1Function
import io.shuttle.mbe.api.types.VoidFunction
import io.shuttle.mbe.core.JSObject
import io.shuttle.mbe.core.Promise

////////////////////
// declarativeNetRequest
////////////////////
/**
 * The `Browser.declarativeNetRequest` API is used to block or modify network requests by specifying declarative rules. This lets extensions modify network requests without intercepting them and viewing their content, thus providing more privacy.
 *
 * Permissions: "declarativeNetRequest", "declarativeNetRequestWithHostAccess", "declarativeNetRequestFeedback"
 *
 * Manifest: "host_permissions"
 * @since Chrome 84
 */
@ChromeMinVersion(84)
interface DeclarativeNetRequest {
    // Ruleset ID for the dynamic rules added by the extension. default is "_dynamic"
    val DYNAMIC_RULESET_ID: String

    // Time interval within which MAX_GETMATCHEDRULES_CALLS_PER_INTERVAL getMatchedRules calls can be made, specified in minutes. Additional calls will fail immediately and set runtime.lastError. Note: getMatchedRules calls associated with a user gesture are exempt from the quota. default is 10
    val GETMATCHEDRULES_QUOTA_INTERVAL: Int

    // The minimum number of static rules guaranteed to an extension across its enabled static rulesets. Any rules above this limit will count towards the global static rule limit. default is  30000
    @ChromeMinVersion(89)
    val GUARANTEED_MINIMUM_STATIC_RULES: Int

    // The number of times getMatchedRules can be called within a period of GETMATCHEDRULES_QUOTA_INTERVAL. default is  20
    val MAX_GETMATCHEDRULES_CALLS_PER_INTERVAL: Int

    // The maximum number of dynamic rules that an extension can add. default is 30000
    val MAX_NUMBER_OF_DYNAMIC_RULES: Int

    // The maximum number of static Rulesets an extension can enable at any one time. default is 50
    @ChromeMinVersion(94)
    val MAX_NUMBER_OF_ENABLED_STATIC_RULESETS: Int

    // The maximum number of regular expression rules that an extension can add. This limit is evaluated separately for the set of dynamic rules and those specified in the rule resources file. default is 1000
    val MAX_NUMBER_OF_REGEX_RULES: Int

    // The maximum number of session scoped rules that an extension can add. default is 5000
    @ChromeMinVersion(120)
    val MAX_NUMBER_OF_SESSION_RULES: Int

    // The maximum number of static Rulesets an extension can specify as part of the "rule_resources" manifest key. default is 100
    val MAX_NUMBER_OF_STATIC_RULESETS: Int

    // The maximum number of "unsafe" dynamic rules that an extension can add. default is 5000
    @ChromeMinVersion(120)
    val MAX_NUMBER_OF_UNSAFE_DYNAMIC_RULES: Int

    // The maximum number of "unsafe" session scoped rules that an extension can add. default is 5000
    @ChromeMinVersion(120)
    val MAX_NUMBER_OF_UNSAFE_SESSION_RULES: Int

    // Ruleset ID for the session-scoped rules added by the extension. default is "_session"
    @ChromeMinVersion(90)
    val SESSION_RULESET_ID: String

    // Returns the number of static rules an extension can enable before the global static rule limit is reached.
    @ChromeMinVersion(89)
    @PromiseStyleMinVersion(91)
    fun getAvailableStaticRuleCount(callback: Value1Function<Number>? = null): Promise<Number>

    // Returns the Array of static rules in the given Ruleset that are currently disabled.
    @ChromeMinVersion(111)
    @PromiseStyleMinVersion(91)
    fun getDisabledRuleIds(
        options: GetDisabledRuleIdsOptions,
        callback: Value1Function<List<Number>>? = null
    ): Promise<List<Number>>

    // Returns the current set of dynamic rules for the extension. Callers can optionally filter the Array of fetched rules by specifying a filter.
    @PromiseStyleMinVersion(91)
    fun getDynamicRules(
        @ChromeMinVersion(111)
        filter: GetRulesFilter?,
        callback: Value1Function<List<DeclarativeNetRequest.Rule>>? = null
    ): Promise<List<Rule>>

    // Returns the ids for the current set of enabled static rulesets.
    @PromiseStyleMinVersion(91)
    fun getEnabledRulesets(callback: Value1Function<List<String>>? = null): Promise<List<String>>

    // Returns all rules matched for the extension. Callers can optionally filter the Array of matched rules by specifying a filter. This method is only available to extensions with the "declarativeNetRequestFeedback" permission or having the "activeTab" permission granted for the tabId specified in filter. Note: Rules not associated with an active document that were matched more than five minutes ago will not be returned.
    @PromiseStyleMinVersion(91)
    fun getMatchedRules(
        filter: MatchedRulesFilter?,
        callback: Value1Function<RulesMatchedDetails>? = null
    ): Promise<RulesMatchedDetails>

    // Returns the current set of session scoped rules for the extension. Callers can optionally filter the Array of fetched rules by specifying a filter.
    @ChromeMinVersion(90)
    @PromiseStyleMinVersion(91)
    fun getSessionRules(
        @ChromeMinVersion(111)
        filter: GetRulesFilter?,
        callback: Value1Function<List<DeclarativeNetRequest.Rule>>? = null
    ): Promise<List<Rule>>

    // Checks if the given regular expression will be supported as a regexFilter rule condition.
    @ChromeMinVersion(87)
    @PromiseStyleMinVersion(91)
    fun isRegexSupported(
        regexOptions: RegexOptions,
        callback: Value1Function<IsRegexSupportedResult>? = null
    ): Promise<IsRegexSupportedResult>

    // Configures if the action count for tabs should be displayed as the extension action's badge text and provides a way for that action count to be incremented.
    @ChromeMinVersion(88)
    @PromiseStyleMinVersion(91)
    fun setExtensionActionOptions(
        options: ExtensionActionOptions,
        callback: VoidFunction? = null
    ): Promise<Void>

    // Checks if any of the extension's declarativeNetRequest rules would match a hypothetical request. Note: Only available for unpacked extensions as this is only intended to be used during extension development.
    @ChromeMinVersion(103)
    @PromiseStyleMinVersion(91)
    fun testMatchOutcome(
        requestDetails: TestMatchRequestDetails,
        callback: Value1Function<TestMatchOutcomeResult>? = null
    ): Promise<TestMatchOutcomeResult>

    // Modifies the current set of dynamic rules for the extension. The rules with IDs listed in options.removeRuleIds are first removed, and then the rules given in options.addRules are added. Notes:
    //
    //This update happens as a single atomic operation: either all specified rules are added and removed, or an error is returned.
    //These rules are persisted across browser sessions and across extension updates.
    //Static rules specified as part of the extension package can not be removed using this function.
    //MAX_NUMBER_OF_DYNAMIC_RULES is the maximum number of dynamic rules an extension can add. The number of unsafe rules must not exceed MAX_NUMBER_OF_UNSAFE_DYNAMIC_RULES.
    @PromiseStyleMinVersion(91)
    fun updateDynamicRules(
        @ChromeMinVersion(87)
        options: UpdateRuleOptions, callback: VoidFunction? = null
    ): Promise<Void>

    // Updates the set of enabled static rulesets for the extension. The rulesets with IDs listed in options.disableRulesetIds are first removed, and then the rulesets listed in options.enableRulesetIds are added. Note that the set of enabled static rulesets is persisted across sessions but not across extension updates, i.e. the rule_resources manifest key will determine the set of enabled static rulesets on each extension update.
    @PromiseStyleMinVersion(91)
    fun updateEnabledRulesets(
        @ChromeMinVersion(87)
        options: UpdateRuleOptions, callback: VoidFunction? = null
    ): Promise<Void>

    // Modifies the current set of session scoped rules for the extension. The rules with IDs listed in options.removeRuleIds are first removed, and then the rules given in options.addRules are added. Notes:
    //
    //This update happens as a single atomic operation: either all specified rules are added and removed, or an error is returned.
    //These rules are not persisted across sessions and are backed in memory.
    //MAX_NUMBER_OF_SESSION_RULES is the maximum number of session rules an extension can add.
    @ChromeMinVersion(90)
    @PromiseStyleMinVersion(91)
    fun updateSessionRules(
        options: UpdateRuleOptions,
        callback: VoidFunction? = null
    ): Promise<Void>

    // Disables and enables individual static rules in a Ruleset. Changes to rules belonging to a disabled Ruleset will take effect the next time that it becomes enabled.
    @ChromeMinVersion(111)
    @PromiseStyleMinVersion(91)
    fun updateStaticRules(
        options: UpdateStaticRulesOptions,
        callback: VoidFunction? = null
    ): Promise<Void>

    // Fired when a rule is matched with a request. Only available for unpacked extensions with the "declarativeNetRequestFeedback" permission as this is intended to be used for debugging purposes only.
    val onRuleMatchedDebug: Events.Event<Value1Function<MatchedRuleInfoDebug>>


    // This describes whether the request is first or third party to the frame in which it originated.
    // A request is said to be first party if it has the same domain (eTLD+1) as the frame in which
    // the request originated.
    enum class DomainType {
        firstParty,
        thirdParty,
    }

    @ChromeMinVersion(88)
    data class ExtensionActionOptions(
        // Whether to automatically display the action count for a page as the extension's badge text.
        // This preference is persisted across sessions.
        var displayActionCountAsBadgeText: Boolean?,
        // Details of how the tab's action count should be adjusted.
        @ChromeMinVersion(89)
        var tabUpdate: TabActionCountUpdate
    )

    @ChromeMinVersion(111)
    data class GetDisabledRuleIdsOptions(
        // The id corresponding to a static Ruleset.
        var rulesetId: String,
    )

    @ChromeMinVersion(111)
    data class GetRulesFilter(
        // If specified, only rules with matching IDs are included.
        var ruleIds: List<Number>?,
    )

    @ChromeMinVersion(128)
    data class HeaderInfo(
        // If specified, this condition is not matched if the header exists but its value contains at least one element in this Array.
        // This uses the same match pattern syntax as values.
        var excludedValues: List<String>?,
        // The name of the header. This condition matches on the name only if both values and excludedValues are not specified.
        var header: String,
        // If specified, this condition matches if the header's value matches at least one pattern in this Array. This supports case-insensitive header value matching plus the following constructs:
        // '*' : Matches any number of characters.
        // '?' : Matches zero or one character(s).
        // '*' and '?' can be escaped with a backslash, e.g. '\*' and '\?'
        var values: List<String>?,
    )

    // This describes the possible operations for a "modifyHeaders" rule.
    @ChromeMinVersion(86)
    enum class HeaderOperation {
        // Adds a new entry for the specified header. This operation is not supported for request headers.
        append,

        // Sets a new value for the specified header, removing any existing headers with the same name.
        set,

        // Removes all entries for the specified header.
        remove,
    }

    @ChromeMinVersion(87)
    data class IsRegexSupportedResult(
        var isSupported: Boolean,
        // Specifies the reason why the regular expression is not supported. Only provided if isSupported is false.
        var reason: UnsupportedRegexReason?,
    )

    // Describes the reason why a given regular expression isn't supported.
    @ChromeMinVersion(87)
    enum class UnsupportedRegexReason {
        // The regular expression is syntactically incorrect, or uses features not available in the RE2 syntax.
        syntaxError,
        // The regular expression exceeds the memory limit.
        memoryLimitExceeded,
    }

    @ChromeMinVersion(89)
    data class TabActionCountUpdate(
        // The amount to increment the tab's action count by. Negative values will decrement the count.
        var increment: Number,
        // The tab for which to update the action count.
        var tabId: Number,
    )

    data class MatchedRule(
        // A matching rule's ID.
        var ruleId: Number,
        // ID of the Ruleset this rule belongs to. For a rule originating from the set of dynamic rules,
        // this will be equal to DYNAMIC_RULESET_ID.
        val rulesetId: String,
    )

    data class MatchedRuleInfo(
        var rule: MatchedRule,
        // The tabId of the tab from which the request originated if the tab is still active. Else -1.
        var tabId: Number,
        // The time the rule was matched. Timestamps will correspond to the Javascript convention for times,
        // i.e. number of milliseconds since the epoch.
        var timeStamp: Number,
    )

    data class MatchedRuleInfoDebug(
        // Details about the request for which the rule was matched.
        var request: JSObject,
        var rule: MatchedRule,
    )

    data class MatchedRulesFilter(
        // If specified, only matches rules after the given timestamp.
        var minTimeStamp: Number?,
        // If specified, only matches rules for the given tab. Matches rules not associated with any active tab if set to -1.
        var tabId: Number?,
    )

    @ChromeMinVersion(86)
    data class ModifyHeaderInfo(
        // The name of the header to be modified.
        var header: String,
        // The operation to be performed on a header.
        var operation: HeaderOperation,
        // The new value for the header. Must be specified for append and set operations.
        var value: String?,
    )

    data class QueryKeyValue(
        var key: String,
        // If true, the query key is replaced only if it's already present. Otherwise, the key is also added if it's missing. Defaults to false.
        @ChromeMinVersion(94)
        var replaceOnly: Boolean?,
        var value: String
    )

    data class QueryTransform(
        // The Array of query key-value pairs to be added or replaced.
        var addOrReplaceParams: List<QueryKeyValue>,
        // The Array of query keys to be removed.
        var removeParams: List<String>?,
    )

    data class Redirect(
        // Path relative to the extension directory. Should start with '/'.
        var extensionPath: String?,
        // Substitution pattern for rules which specify a regexFilter. The first match of regexFilter within the url will be replaced with this pattern. Within regexSubstitution, backslash-escaped digits (\1 to \9) can be used to insert the corresponding capture groups. \0 refers to the entire matching text.
        var regexSubstitution: String?,
        // Url transformations to perform.
        var transform: JSObject,
        // The redirect url. Redirects to JavaScript urls are not allowed.
        var url: String?,
    )

    @ChromeMinVersion(87)
    data class RegexOptions(
        // Whether the regex specified is case sensitive. Default is true.
        var isCaseSensitive: Boolean?,
        // The regular expresson to check.
        var regex: String,
        // Whether the regex specified requires capturing. Capturing is only required for redirect rules which specify a regexSubstition action. The default is false.
        var requireCapturing: Boolean?,
    )

    data class RequestDetails(
        // The unique identifier for the frame's document, if this request is for a frame.
        @ChromeMinVersion(106)
        var documentId: String?,
        // The lifecycle of the frame's document, if this request is for a frame.
        @ChromeMinVersion(106)
        var documentLifecycle: JSObject,
        // The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.
        var frameId: Number,
        // The type of the frame, if this request is for a frame.
        var frameType: JSObject,
        // The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used.
        var initiator: String?,
        // Standard HTTP method.
        var method: String,
        // The unique identifier for the frame's parent document, if this request is for a frame and has a parent.
        var parentDocumentId: String?,
        // ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists.
        var parentFrameId: Number,
        // The ID of the request. Request IDs are unique within a browser session.
        var requestId: String,
        // The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab.
        var tabId: Number,
        // The resource type of the request.
        var type: ResourceType,
        // The URL of the request.
        var url: String,
    )

    // This describes the HTTP request method of a network request.
    @ChromeMinVersion(91)
    enum class RequestMethod {
        connect,
        delete,
        get,
        head,
        options,
        patch,
        post,
        put,
        other
    }

    // This describes the resource type of the network request.
    enum class ResourceType {
        main_frame,
        sub_frame,
        stylesheet,
        script,
        image,
        font,
        `object`,
        xmlhttprequest,
        ping,
        csp_report,
        media,
        websocket,
        webtransport,
        webbundle,
        other,
    }

    data class Rule(
        // The action to take if this rule is matched.
        var action: RuleAction,
        // The condition under which this rule is triggered.
        var condition: RuleCondition,
        // An id which uniquely identifies a rule. Mandatory and should be >= 1.
        var id: Number,
        // Rule priority. Defaults to 1. When specified, should be >= 1.
        var priority: Number?,
    )

    data class RuleAction(
        // Describes how the redirect should be performed. Only valid for redirect rules.
        var redirect: Redirect?,
        // The request headers to modify for the request. Only valid if RuleActionType is "modifyHeaders".
        @ChromeMinVersion(86)
        var requestHeaders: List<ModifyHeaderInfo>?,
        // The response headers to modify for the request. Only valid if RuleActionType is "modifyHeaders".
        @ChromeMinVersion(86)
        var responseHeaders: List<ModifyHeaderInfo>?,
        // The type of action to perform.
        var type: RuleActionType,
    )

    // Describes the kind of action to take if a given RuleCondition matches.
    enum class RuleActionType {
        // Block the network request.
        block,

        // Redirect the network request.
        redirect,

        // Allow the network request. The request won't be intercepted if there is an allow rule which matches it.
        allow,

        // Upgrade the network request url's scheme to https if the request is http or ftp.
        upgradeScheme,

        // Modify request/response headers from the network request.
        modifyHeaders,

        // Allow all requests within a frame hierarchy, including the frame request itself.
        allowAllRequests
    }

    data class RuleCondition(
        // Specifies whether the network request is first-party or third-party to the domain from which it originated. If omitted, all requests are accepted.
        var domainType: DomainType?,
        // The rule will only match network requests originating from the Array of domains.
        @Deprecated("Deprecated since Chrome 101", ReplaceWith("Use initiatorDomains instead"))
        var domains: List<String>?,
        // The rule will not match network requests originating from the Array of excludedDomains.
        @Deprecated(
            "Deprecated since Chrome 101",
            ReplaceWith("Use excludedInitiatorDomains instead")
        )
        var excludedDomains: List<String>?,
        // The rule will not match network requests originating from the Array of excludedInitiatorDomains. If the Array is empty or omitted, no domains are excluded. This takes precedence over initiatorDomains.
        // Notes:
        // Sub-domains like "a.example.com" are also allowed.
        // The entries must consist of only ascii characters.
        // Use punycode encoding for internationalized domains.
        // This matches against the request initiator and not the request url.
        // Sub-domains of the listed domains are also excluded.
        @ChromeMinVersion(101)
        var excludedInitiatorDomains: List<String>?,
        // The rule will not match network requests when the domains matches one from the Array of excludedRequestDomains. If the Array is empty or omitted, no domains are excluded. This takes precedence over requestDomains.
        // Notes:
        //
        //  Sub-domains like "a.example.com" are also allowed.
        //  The entries must consist of only ascii characters.
        //  Use punycode encoding for internationalized domains.
        //  Sub-domains of the listed domains are also excluded.
        @ChromeMinVersion(101)
        var excludedRequestDomains: List<String>?,
        // Array of request methods which the rule won't match. Only one of requestMethods and excludedRequestMethods should be specified. If neither of them is specified, all request methods are matched.
        @ChromeMinVersion(91)
        var excludedRequestMethods: List<RequestMethod>?,
        // Array of resource types which the rule won't match. Only one of resourceTypes and excludedResourceTypes should be specified. If neither of them is specified, all resource types except "main_frame" are blocked.
        var excludedResourceTypes: List<ResourceType>?,
        // Rule does not match if the request matches any response header condition in this Array (if specified). If both excludedResponseHeaders and responseHeaders are specified, then the excludedResponseHeaders property takes precedence.
        @ChromeMinVersion(128)
        var excludedResponseHeaders: List<HeaderInfo>?,
        // Array of tabs.Tab.id which the rule should not match. An ID of tabs.TAB_ID_NONE excludes requests which don't originate from a tab. Only supported for session-scoped rules.
        @ChromeMinVersion(92)
        var excludedTabIds: List<Number>?,
        // The rule will only match network requests originating from the Array of initiatorDomains. If the Array is omitted, the rule is applied to requests from all domains. An empty Array is not allowed.
        //
        //Notes:
        //
        //Sub-domains like "a.example.com" are also allowed.
        //The entries must consist of only ascii characters.
        //Use punycode encoding for internationalized domains.
        //This matches against the request initiator and not the request url.
        //Sub-domains of the listed domains are also matched.
        @ChromeMinVersion(101)
        var initiatorDomains: List<String>?,
        // Whether the urlFilter or regexFilter (whichever is specified) is case sensitive. Default is false.
        var isUrlFilterCaseSensitive: Boolean? = false,
        // Regular expression to match against the network request url. This follows the RE2 syntax.
        //
        //Note: Only one of urlFilter or regexFilter can be specified.
        //
        //Note: The regexFilter must be composed of only ASCII characters. This is matched against a url where the host is encoded in the punycode format (in case of internationalized domains) and any other non-ascii characters are url encoded in utf-8.
        var regexFilter: String?,
        // The rule will only match network requests when the domain matches one from the Array of requestDomains. If the Array is omitted, the rule is applied to requests from all domains. An empty Array is not allowed.
        //
        //Notes:
        //
        //Sub-domains like "a.example.com" are also allowed.
        //The entries must consist of only ascii characters.
        //Use punycode encoding for internationalized domains.
        //Sub-domains of the listed domains are also matched.
        @ChromeMinVersion(101)
        var requestDomains: List<String>?,
        // Array of HTTP request methods which the rule can match. An empty Array is not allowed.
        //
        //Note: Specifying a requestMethods rule condition will also exclude non-HTTP(s) requests, whereas specifying excludedRequestMethods will not.
        @ChromeMinVersion(91)
        var requestMethods: List<RequestMethod>?,
        // Array of resource types which the rule can match. An empty Array is not allowed.
        //
        //Note: this must be specified for allowAllRequests rules and may only include the sub_frame and main_frame resource types.
        var resourceTypes: List<ResourceType>?,
        // Rule matches if the request matches any response header condition in this Array (if specified).
        @ChromeMinVersion(128)
        var responseHeaders: List<HeaderInfo>?,
        // Array of tabs.Tab.id which the rule should match. An ID of tabs.TAB_ID_NONE matches requests which don't originate from a tab. An empty Array is not allowed. Only supported for session-scoped rules.
        @ChromeMinVersion(92)
        var tabIds: List<Number>?,
        // The pattern which is matched against the network request url. Supported constructs:
        //
        //'*' : Wildcard: Matches any number of characters.
        //
        //'|' : Left/right anchor: If used at either end of the pattern, specifies the beginning/end of the url respectively.
        //
        //'||' : Domain name anchor: If used at the beginning of the pattern, specifies the start of a (sub-)domain of the URL.
        //
        //'^' : Separator character: This matches anything except a letter, a digit, or one of the following: _, -, ., or %. This also match the end of the URL.
        //
        //Therefore urlFilter is composed of the following parts: (optional Left/Domain name anchor) + pattern + (optional Right anchor).
        //
        //If omitted, all urls are matched. An empty string is not allowed.
        //
        //A pattern beginning with ||* is not allowed. Use * instead.
        //
        //Note: Only one of urlFilter or regexFilter can be specified.
        //
        //Note: The urlFilter must be composed of only ASCII characters. This is matched against a url where the host is encoded in the punycode format (in case of internationalized domains) and any other non-ascii characters are url encoded in utf-8. For example, when the request url is http://abc.рф?q=ф, the urlFilter will be matched against the url http://abc.xn--p1ai/?q=%D1%84.
        var urlFilter: String?,
    )

    data class Ruleset(
        // Whether the ruleset is enabled by default.
        var enabled: Boolean,
        // A non-empty string uniquely identifying the ruleset. IDs beginning with '_' are reserved for internal use.
        var id: String,
        // The path of the JSON ruleset relative to the extension directory.
        var path: String,
    )

    data class RulesMatchedDetails(
        // Rules matching the given filter.
        var rulesMatchedInfo: List<MatchedRuleInfo>,
    )

    @ChromeMinVersion(103)
    data class TestMatchOutcomeResult(
        // The rules (if any) that match the hypothetical request.
        var matchedRules: List<MatchedRule>,
    )

    @ChromeMinVersion(103)
    data class TestMatchRequestDetails(
        // The initiator URL (if any) for the hypothetical request.
        var initiator: String?,
        // Standard HTTP method of the hypothetical request. Defaults to "get" for HTTP requests and is ignored for non-HTTP requests.
        var method: RequestMethod?,
        // The headers provided by a hypothetical response if the request does not get blocked or redirected before it is sent. Represented as an object which maps a header name to a Array of string values. If not specified, the hypothetical response would return empty response headers, which can match rules which match on the non-existence of headers. E.g. {"content-type": ["text/html; charset=utf-8", "multipart/form-data"]}
        @ChromeMinVersion(129)
        var responseHeaders: Any,
        // The ID of the tab in which the hypothetical request takes place. Does not need to correspond to a real tab ID. Default is -1, meaning that the request isn't related to a tab.
        var tabId: Number?,
        // The resource type of the hypothetical request.
        var type: ResourceType,
        // The URL of the hypothetical request.
        var url: String,
    )

    @ChromeMinVersion(87)
    data class UpdateRuleOptions(
        // IDs of the rules to remove. Any invalid IDs will be ignored.
        var addRules: List<Rule>?,
    )

    @ChromeMinVersion(87)
    data class UpdateRulesetOptions(
        // The set of ids corresponding to a static Ruleset that should be disabled.
        var disableRulesetIds: List<String>?,
        // The set of ids corresponding to a static Ruleset that should be enabled.
        var enableRulesetIds: List<String>?,
    )

    @ChromeMinVersion(111)
    data class UpdateStaticRulesOptions(
        // Set of ids corresponding to rules in the Ruleset to disable.
        var disableRuleIds: List<Number>?,
        // Set of ids corresponding to rules in the Ruleset to enable.
        var enableRuleIds: List<Number>?,
        // The id corresponding to a static Ruleset.
        var rulesetId: String,
    )

    data class URLTransform(
        // The new fragment for the request. Should be either empty, in which case the existing fragment is cleared; or should begin with '#'.
        var fragment: String?,
        // The new host for the request.
        var host: String?,
        // The new password for the request.
        var password: String?,
        // The new path for the request. If empty, the existing path is cleared.
        var path: String?,
        // The new port for the request. If empty, the existing port is cleared.
        var port: String?,
        // The new query for the request. Should be either empty, in which case the existing query is cleared; or should begin with '?'.
        var query: String?,
        // Add, remove or replace query key-value pairs.
        var queryTransform: QueryTransform?,
        // The new scheme for the request. Allowed values are "http", "https", "ftp" and "chrome-extension".
        var scheme: String?,
        // The new username for the request.
        var username: String?,
    )
}